/***********************************************************************
    filename:   DaterEventFactory.h
    created:    10/4/2012
    author:     4Ys

    purpose:    Defines abstract base class for EventFactory objects
*************************************************************************/
#ifndef _DaterEventFactory_h_
#define _DaterEventFactory_h_

#include "DaterEvent.h"

/*!
\brief
    Declares a event factory class.

\param T
    The event class name.

\note
    The class that will be generated is is named &lt;classname&gt;Factory.
    A statement like this:
        CEGUI_DECLARE_EVENT_FACTORY(MyEvent);
    Would generate a factory class named MyEventFactory.

    The factory is automatically instantiated and for the example it would
    be available as:
        EventFactory* wf = &(getMyEventFactory());
    or
        EventFactory* wf = &DATER_EVENT_FACTORY(MyEvent);
*/
#define DATER_DECLARE_EVENT_FACTORY( T )\
    class T ## Factory : public EventFactory\
    {\
    public:\
        T ## Factory() : EventFactory( T::EventTypeName ) {}\
        Event* createEvent(const std::string& name,const Time& startTime, const Time& finishTime, const std::string& description, int userID, long uid)\
        {\
            return new T(_type, name, startTime, finishTime, description, userID, uid);\
        }\
        void destroyEvent(Event* theEvent)\
        {\
            delete theEvent;\
        }\
    };\
    T ## Factory& get ## T ## Factory();

/*!
\brief
    Generates code for the constructor for the instance of the event factory
    generated from the class name \a T
*/
#define DATER_DEFINE_EVENT_FACTORY( T )\
    T ## Factory& get ## T ## Factory()\
    {\
        static T ## Factory s_factory;\
        return s_factory;\
    }

/*!
\brief
    Helper macro that return the real factory class name from a given class
    name \a T
*/
#define DATER_EVENT_FACTORY( T ) (get ## T ## Factory())

namespace Dater
{

	class EventFactory
	{
	public:
		virtual Event* createEvent(const std::string& name,const Time& startTime, 
			const Time& finishTime, const std::string& description, int userID, long uid) = 0;
		virtual void destoryEvent(Event* theEvent) = 0;
		virtual ~EventFactory() {}
		const std::string& getTypeName() const
		{return _type;}

	protected:
		EventFactory(const std::string& type) : _type(type) {}
		std::string _type;
	};

}

#endif